﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Gui
{
    abstract class Menu
    {
        protected List<MenuItem> menu;
        protected List<bool> activeItems;
        private Style activeStyle;
        private int lastChoice;
        public Style ActiveStyle { get { return activeStyle; } protected set { activeStyle = value; } }
        public int LastChoice { get { return lastChoice; } private set { lastChoice = value; } }

        public Menu(string[] args)
        {
            menu = new List<MenuItem>();
            activeItems = new List<bool>();
            run(args);
        }


        private string showMenu()
        {

            string m = "\n0: Exit\n";
            for (int i = 0; i < menu.Count; i++)
            {
                m += (activeItems[i] ? (i + 1) + ":" : "-:") + " " + menu[i] + "\n";
            }

            return m;
        }

        public void run(string[] args)
        {
            Console.BackgroundColor = ConsoleColor.Black;
            initiateMenu();
            if (activeStyle == null)
                activeStyle = new DefaultStyle();
            StartupArguments(args);

            while (true)
            {
                try
                {
                    activeStyle.PrintMenuTop();
                    Console.Write(showMenu());
                    activeStyle.PrintMenuBottom();
                    activeStyle.PrintPickText();
                    string input = Console.ReadLine();
                    activeStyle.PrintMenuItemExecuteStart();
                    int choise = Convert.ToInt32(input);
                    lastChoice = choise;
                    if (choise == 0)
                    { break; }
                    choose(choise);
                }
                catch (Exception e)
                {
                    activeStyle.PrintMenuException(e);
                }
                finally
                {
                    activeStyle.PrintMenuItemExecuteEnd();
                }
            }
            activeStyle.PrintCreatorSignature();
            Console.WriteLine("\n**Menu created by Anders Madsen, Easv Denmark bachelor graduate 2014**\n");
        }
        protected abstract void MenuStartingArgs(string[] args);
        private void StartupArguments(string[] args)
        {
            MenuStartingArgs(args);
        }

        
        /// <summary>
        /// picks a menuitem to execute and runs menuitemcheck on the choice
        /// nonvalid picks (arrayoutof bound and menuitems marked as unavailable) are dealt with
        /// </summary>
        /// <param name="choise">the choice of item in the menu</param>
        protected void choose(int choise)
        {
            choise--;
            try{
            
                pick(choise);
                menuItemCheck(choise);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n" + e.StackTrace);
            }
        }

        protected abstract void menuItemCheck(int choise);

        private void pick(int choise)
        {
            Console.WriteLine();
            if (choise >= menu.Count || !activeItems[choise])
                throw new Exception("No menuoption with the number " + ++choise);
            else
                menu[choise].Execute();
        }

        abstract protected void initiateMenu();
        protected void add(MenuItem item)
        {
            add(item, true);
        }
        protected void add(MenuItem item, bool activated)
        {
            menu.Add(item);
            activeItems.Add(activated);
        }
    }
}
